from models import MetricSite, MetricSet, MetricDefn
from types import DictType

def sync_provider_to_db(metric_provider, site_name, site_check_mins):
    """
    Inspects metric_provider object to populate database objects
    """
    
    print "syncing to provider"
    # Does metric site exist yet?
    site = get_create_update_metric_site(site_name, site_check_mins)
    
    for (setname, setdefn) in metric_provider.sets.iteritems():
        set = get_create_update_metric_set(setname, setdefn, site)
        for (defn_name, defn_function) in setdefn.stats.iteritems():
            defn = get_create_update_metric_defn(defn_name, defn_function, set)
    
    # Return site for convenience
    return site

def get_create_update_metric_site(site_name, site_check_mins):
    try:
        site = MetricSite.objects.get(name=site_name)
        if site.check_mins != site_check_mins:
            print "Updating metric_site %s with site_check_mins %s" % (site_name, site_check_mins)
            site.check_mins = site_check_mins
            site.save()
    except MetricSite.DoesNotExist:
        print "Creating metric_site %s with site_check_mins %s" % (site_name, site_check_mins)
        site = MetricSite(name=site_name, check_mins=site_check_mins)
        site.save()

    return site

def get_create_update_metric_set(set_name, defn, site):
    description = defn.description
    collection_mins = defn.collection_mins
    shadow_mins = defn.shadow_mins

    try:
        set = MetricSet.objects.get(name=set_name)
        if set.description != description or set.collection_mins != collection_mins or set.shadow_mins != shadow_mins:
            print "Updating metric_set %s with parameters description=%s, collection_mins=%d, shadow_mins=%d" % (set_name, description, collection_mins, shadow_mins)
            set.description = description
            set.collection_mins = collection_mins
            set.shadow_mins = shadow_mins
            set.save()
    except MetricSet.DoesNotExist:
        print "Creating metric_set %s with parameters description=%s, collection_mins=%d, shadow_mins=%d" % (set_name, description, collection_mins, shadow_mins)
        set = MetricSet(metricsite=site, name=set_name, description=description, collection_mins=collection_mins, shadow_mins=shadow_mins)
        set.save()

    return set

def get_create_update_metric_defn(defn_name, defn_function, set):
    description = getattr(defn_function, '__doc__')
    if description is None: # lambda's __doc__ exists and is None.
        description = "No defn description"
    else:
        description = description.replace("\n", " ").strip()
    
    try:
        defn = MetricDefn.objects.get(metricset=set, name=defn_name)
        if defn.description != description:
            print "Updating metric_defn %s with description %s, in set %s" % (defn_name, description, set.name)
            defn.description = description
            defn.save()
    except MetricDefn.DoesNotExist:
        print "Creating metric_defn %s with description %s, in set %s" % (defn_name, description, set.name)
        defn = MetricDefn(metricset=set, name=defn_name, description=description)
        defn.save()

    return defn
